package com.xbongbong.parent.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONException;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.domain.entity.ext.OptionalRangeEntity;
import com.xbongbong.paas.enums.DelEnum;
import com.xbongbong.paas.enums.OptionalRangeEnum;
import com.xbongbong.saas.domain.entity.PublicGroupEntity;
import com.xbongbong.sys.domain.entity.DepartmentEntity;
import com.xbongbong.sys.domain.entity.UserEntity;
import com.xbongbong.sys.model.DepartmentModel;
import com.xbongbong.sys.model.UserModel;
import com.xbongbong.sys.util.UserUtil;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * @author 吴峰
 * @date 2021/12/16 15:15
 */
@Service("listGroupServiceImpl")
public class ListGroupServiceImpl implements ListGroupService {

    @Resource
    private DepartmentModel departmentModel;
    @Resource
    private UserModel userModel;

    @Override
    public List<PublicGroupEntity> filterGroupByUser(List<PublicGroupEntity> list, UserEntity user) {
        List<PublicGroupEntity> resultList = new ArrayList<>();
        // 角色数据
        List<Integer> roleIds = user.roleIdsToList();
        // 部门列表
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", user.getCorpid());
        param.put("del", DelEnum.NORMAL.getDel());
        List<DepartmentEntity> allDepartmentList = departmentModel.findEntitys(param);
        // 获得用户所属部门id列表
        List<Long> belongDepList = userModel.getUserBelongDeptIdList(user, false);

        for (PublicGroupEntity entity : list) {
            JSONArray scopeRule = entity.getScopeRule();
            List<OptionalRangeEntity> scopeRuleData;
            try {
                scopeRuleData = scopeRule.toJavaList(OptionalRangeEntity.class);
            } catch (JSONException e) {
                scopeRuleData = new ArrayList<>();
            }
            // 未设置查看权限
            if (scopeRuleData.size() <= 0) {
                resultList.add(entity);
                continue;
            }

            List<Long> depIdArray = new ArrayList<>();
            List<Integer> roleIdArray = new ArrayList<>();
            List<String> userIdArray = new ArrayList<>();

            for (OptionalRangeEntity rangeEntity : scopeRuleData) {
                String property = rangeEntity.getProperty();
                String id = rangeEntity.getId();

                if (OptionalRangeEnum.DEPT.getValue().equals(property)) {
                    depIdArray.add(Long.parseLong(id));
                } else if (OptionalRangeEnum.ROLE.getValue().equals(property)) {
                    roleIdArray.add(Integer.parseInt(id));
                } else if (OptionalRangeEnum.USER.getValue().equals(property)) {
                    userIdArray.add(id);
                }
            }

            // 未设置查看权限
            if (depIdArray.isEmpty() && roleIdArray.isEmpty() && userIdArray.isEmpty()) {
                resultList.add(entity);
                continue;
            }

            // 角色是否有交集
            roleIdArray.retainAll(roleIds);
            if (!roleIdArray.isEmpty()) {
                resultList.add(entity);
                continue;
            }

            // 全公司
            if (depIdArray.contains(1L)) {
                resultList.add(entity);
                continue;
            }

            // 获取有权限查看模板的部门以及子部门
            Set<Long> depIncludeSubSet = new LinkedHashSet<>();
            for (Long depId : depIdArray) {
                Set<Long> subDepIdList = UserUtil.getSubDepIdList(depId, allDepartmentList);
                depIncludeSubSet.addAll(subDepIdList);
            }
            depIncludeSubSet.retainAll(belongDepList);
            if (!depIncludeSubSet.isEmpty()) {
                resultList.add(entity);
                continue;
            }

            // 自定义人员匹配
            if (userIdArray.contains(user.getUserId())) {
                resultList.add(entity);
            }

        }
        return resultList;
    }
}
